#include "gl_hershey.h"

#include <cstring>
#include <cstdarg>
#include <cstdio>
#include <vector>
#include <gl\glfw.h>
#include <math.h>
#include "simplexFont.h"

HersheyText* HersheyText::_instance = 0x0;

HersheyText* HersheyText::Instance()
{ 
	if( !_instance )
	{
		_instance = new HersheyText();
	}
	return _instance;
}

void HersheyText::moveTo(float x, float y)
{
    moveToX = x;
    moveToY = y;
}

void HersheyText::lineTo(float x, float y)
{	
    glBegin(GL_LINES);
        glVertex2f( moveToX , moveToY );
        glVertex2f( x,y);
    glEnd();
    moveToX = x;
    moveToY = y;
}

void HersheyText::drawChar(int c,float scale){
	int verts = simplex[c][0];
	//float spacing = simplex[c][1]; // used in glPrintf to move tx

	float ax = simplex[c][2];
	float ay = simplex[c][3]; 
	moveTo( (tx+ax*scale-scale*2.0f), (ty-ay*scale+scale*2.0f) );  
	int i=0;
	for(i=4; i<verts*2; i+=2)
		{
		ax = simplex[c][i+0];
		ay = simplex[c][i+1];

		if(ax==-1 || ay == -1) 
			moveTo(tx+simplex[c][i+2]*scale-scale*2.0f, (ty-simplex[c][i+3]*scale+scale*2.0f) );
		else 
			lineTo( (tx+ax*scale-scale*2.0f), (ty-ay*scale+scale*2.0f) );        
	}
	lineTo( (tx+simplex[c][i+0]*scale-scale*2.0f) , ( ty-simplex[c][i+1]*scale+scale*2.0f ) );
}


void HersheyText::setFont(float w, float h)
{
	textW = w/20; textH = h/20;
}

void HersheyText::glPrintf(const char *format,...)
{
    if (format == NULL) return;
    float sx = moveToX;
    //float sy = moveToY;
    tx=moveToX;
    ty=moveToY;

	std::vector<char> finalText;

	va_list args;
	va_start(args, format);
	// _vscprintf doesn't count terminating '\0' (that's why +1)
	int len = _vscprintf(format, args) + 1;
	finalText.resize(len);

	vsprintf_s(&finalText[0], len, format, args);
	va_end(args);

    int i;
    for (i = 0; i < len; i++) {
        if( finalText[i] == '\n' )
        {
                tx = sx;
                ty += 20*textH;
        }else{
                int c = (int)finalText[i]-32;
                if(c < 0 || c > 94) return;
                {
                        drawChar( c, textW );
                        tx += simplex[c][1]*textW;
                }
        }
    }
    moveToX = sx;
    moveToY = ty;

}

void HersheyText::glPrintf( const std::string &text )
{
	if (text.size() == 0) return;
	float sx = moveToX;
	//float sy = moveToY;
	tx=moveToX;
	ty=moveToY;


	for (size_t i = 0; i < text.size(); i++)
	{
		if( text[i] == '\n' )
		{
			tx = sx;
			ty += 20*textH;
		}else{
			int c = (int)text[i]-32;

			if(c < 0 || c > 94) continue;
			{
				drawChar( c, textW );
				tx += simplex[c][1]*textW;
			}
		}
	}
	moveToX = sx;
	moveToY = ty;
}
